home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre4.z / postgre4 / src / rules / stubs / stubjoin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-27  |  6.4 KB  |  247 lines

  1. /*=======================================================================
  2.  *
  3.  * FILE: stubjoin.c
  4.  *
  5.  * IDENTIFICATION:
  6.  * $Header: /private/postgres/src/rules/stubs/RCS/stubjoin.c,v 1.13 1992/07/04 04:03:56 mao Exp $
  7.  *
  8.  * Routines used when the executor runs in 'rule lock set/remove' mode.
  9.  *
  10.  */
  11. #include "rules/prs2.h"
  12. #include "rules/prs2stub.h"
  13. #include "nodes/primnodes.h"
  14. #include "nodes/primnodes.a.h"
  15. #include "nodes/plannodes.h"
  16. #include "nodes/plannodes.a.h"
  17. #include "access/heapam.h"
  18. #include "utils/log.h"
  19. #include "tmp/datum.h"
  20.  
  21. /*----------------------------------------------------------------
  22.  *
  23.  * prs2MakeStubForInnerRelation
  24.  *
  25.  * Create a `PrsOneStub'. This routine is called during the proccessing
  26.  * of a Join node. For every tuple of the Outer relation, we have to
  27.  * create (and insert in the inner relation) a rule stub.
  28.  *
  29.  *----------------------------------------------------------------
  30.  */
  31. Prs2OneStub
  32. prs2MakeStubForInnerRelation(ruleInfo, tuple, buffer,
  33.                 outerTupleDesc, innerTupleDesc)
  34. JoinRuleInfo ruleInfo;
  35. HeapTuple tuple;
  36. Buffer buffer;
  37. TupleDescriptor outerTupleDesc;
  38. TupleDescriptor innerTupleDesc;
  39. {
  40.     Prs2OneStub oneStub;
  41.     ObjectId ruleId;
  42.     Prs2StubId stubId;
  43.     RuleLock lock;
  44.     LispValue qual;
  45.     AttributeNumber innerAttrNo, outerAttrNo;
  46.     ObjectId operator, type;
  47.     Size len;
  48.     bool byval;
  49.     Datum value, cpvalue;
  50.     Boolean isNull;
  51.     Oper opr;
  52.     Var var;
  53.     Const cnst;
  54.     LispValue varid;
  55.  
  56.  
  57.     operator = get_jri_operator(ruleInfo);
  58.     innerAttrNo = get_jri_inattrno(ruleInfo);
  59.     outerAttrNo = get_jri_outattrno(ruleInfo);
  60.     ruleId = get_jri_ruleid(ruleInfo);
  61.     stubId = get_jri_stubid(ruleInfo);
  62.     lock = get_jri_lock(ruleInfo);
  63.  
  64.     /*
  65.      * now form the stub's qualification. This will correspond to
  66.      * the qualification:
  67.      *    ( <operator> <innerAttrNo> <constant> )
  68.      * where <constant> is the value of the "outerAttrno" of the
  69.      * outer relation tuple "tuple".
  70.      */
  71.     value = HeapTupleGetAttributeValue(
  72.             tuple,
  73.             buffer,
  74.             outerAttrNo,
  75.             outerTupleDesc,
  76.             &isNull);
  77.     if (isNull) {
  78.     /*
  79.      * the outer tuple has a null attribute, so do not do
  80.      * anything.
  81.      */
  82.     return((Prs2OneStub)NULL);
  83.     }
  84.     /*
  85.      * NOTE: make a "copy" of the datum (i.e. of the data pointed
  86.      * by, if any)... Beter be safe (and slow) then sorry...
  87.      */
  88.     type = outerTupleDesc->data[outerAttrNo-1]->atttypid;
  89.     len = get_typlen(type);
  90.     byval = get_typbyval(type);
  91.     cpvalue = datumCopy(value, type, byval, len);
  92.     cnst = MakeConst(
  93.         type,    /* consttype */
  94.         len,    /* constlen */
  95.         cpvalue,    /* constvalue */
  96.         false,    /* constisnull */
  97.         byval);    /* constbyval */
  98.  
  99.     type = innerTupleDesc->data[innerAttrNo-1]->atttypid;
  100.     len = get_typlen(type);
  101.     byval = get_typbyval(type);
  102.     varid = lispCons(lispInteger(0),
  103.             lispCons(lispInteger(innerAttrNo), LispNil));
  104.     var =  MakeVar(
  105.         (Index) 0,        /* varno */
  106.         innerAttrNo,    /* varattno */
  107.         type,        /* vartype */
  108.         varid,        /* varid */
  109.         InvalidObjectId);    /* varelemtype */
  110.     opr = MakeOper(
  111.         operator,        /* opno */
  112.         InvalidObjectId,    /* opid */
  113.         false,        /* oprelationlevel */
  114.         PRS2_BOOL_TYPEID,    /* opresulttype */
  115.         0,            /* opsize */
  116.         NULL);        /* op_fcache */
  117.     (void) replace_opid(opr);
  118.  
  119.     qual = lispCons((LispValue)opr,
  120.             lispCons((LispValue)var,
  121.                  lispCons((LispValue)cnst, LispNil)));
  122.  
  123.     qual = lispCons(qual, LispNil);
  124.  
  125.     /*
  126.      * OK, now form the 'Prs2OneStub'
  127.      */
  128.     oneStub = prs2MakeOneStub();
  129.     oneStub->ruleId = ruleId;
  130.     oneStub->stubId = stubId;
  131.     oneStub->counter = 1;
  132.     oneStub->lock = lock;
  133.     oneStub->qualification = qual;
  134.     return(oneStub);
  135. }
  136.  
  137. /*----------------------------------------------------------------
  138.  *
  139.  * prs2AddLocksAndReplaceTuple
  140.  *
  141.  * If the qualification associated with the `oneStub' is satisfied
  142.  * by the given tuple, then add a rule lock and return true.
  143.  * Otherwise return false.
  144.  *
  145.  *----------------------------------------------------------------
  146.  */
  147. bool
  148. prs2AddLocksAndReplaceTuple(tuple, buffer, relation, oneStub, newExpLocksFlag)
  149. HeapTuple tuple;
  150. Buffer buffer;
  151. Relation relation;
  152. Prs2OneStub oneStub;
  153. bool *newExpLocksFlag;
  154. {
  155.     RuleLock oldLocks, newLocks, expLocks, temp;
  156.     TupleDescriptor tupDesc;
  157.     ItemPointer tupleId;
  158.     HeapTuple newTuple;
  159.  
  160.     tupDesc = RelationGetTupleDescriptor(relation);
  161.     *newExpLocksFlag = false;
  162.  
  163.     if (prs2StubQualTestTuple(tuple, buffer, tupDesc, oneStub->qualification)) {
  164.     oldLocks = prs2GetLocksFromTuple(tuple, buffer);
  165.     newLocks = prs2LockUnion(oneStub->lock, oldLocks);
  166.     prs2FreeLocks(oldLocks);
  167.     /*
  168.      * If the stub lock was an "import" lock, then this addition
  169.      * might create a new "export" lock for the tuple...
  170.      */
  171.     expLocks = prs2FindNewExportLocksFromLocks(newLocks);
  172.     if (!prs2RuleLockIsEmpty(expLocks)) {
  173.         *newExpLocksFlag = true;
  174.         temp = prs2LockUnion(newLocks, expLocks);
  175.         prs2FreeLocks(newLocks);
  176.         prs2FreeLocks(expLocks);
  177.         newLocks = temp;
  178.     }
  179.     /*
  180.      * create a copy of the tuple & add the locks
  181.      */
  182.     newTuple = palloctup(tuple, buffer, relation);
  183.     prs2PutLocksInTuple(newTuple, buffer, relation, newLocks);
  184.     /*
  185.      * XXX: what happens if this tuple has already been replaced ?
  186.      * Should we check with: TupleUpdatedByCurXactAndCmd() ???
  187.      */
  188.     tupleId = &(tuple->t_ctid);
  189.     amreplace(relation, tupleId, newTuple);
  190.     /*
  191.      * free the new tuple...
  192.      */
  193.     HeapTupleFreeRuleLock(newTuple);
  194.     pfree(newTuple);
  195.     return(true);
  196.     } else {
  197.     return(false);
  198.     }
  199. }
  200.     
  201. /*----------------------------------------------------------------
  202.  *
  203.  * prs2UpdateStats
  204.  *
  205.  * Update statistics associated with rule stub records.
  206.  *----------------------------------------------------------------
  207.  */
  208. void
  209. prs2UpdateStats(ruleInfo, operation)
  210. JoinRuleInfo ruleInfo;
  211. int operation;
  212. {
  213.     Prs2StubStats stats;
  214.  
  215.     stats = get_jri_stats(ruleInfo);
  216.     if (stats == NULL) {
  217.     stats = (Prs2StubStats) palloc(sizeof(Prs2StubStatsData));
  218.     if (stats == NULL) {
  219.         elog(WARN, "prs2UpdateStats: run out of memory");
  220.     }
  221.     stats->stubsAdded = 0;
  222.     stats->stubsDeleted = 0;
  223.     stats->locksAdded = 0;
  224.     stats->locksDeleted = 0;
  225.     }
  226.  
  227.     switch (operation) {
  228.     case PRS2_ADDSTUB:
  229.         stats->stubsAdded += 1;
  230.         break;
  231.     case PRS2_DELETESTUB:
  232.         stats->stubsDeleted += 1;
  233.         break;
  234.     case PRS2_ADDLOCK:
  235.         stats->locksAdded += 1;
  236.         break;
  237.     case PRS2_DELETELOCK:
  238.         stats->locksDeleted += 1;
  239.         break;
  240.     default:
  241.         elog(WARN, "prs2UpdateStats:illegal operation %d",operation);
  242.     }
  243.  
  244.     set_jri_stats(ruleInfo, stats);
  245. }
  246.  
  247.